﻿#define _CRT_SECURE_NO_WARNINGS 1


////2、运行以下程序后，如果从键盘上输入 65 14 < 回车 > ，则输出结果为（ ）
//int main()
//{
//	int m, n;
//	printf("Enter m,n;");
//	scanf("%d%d", &m, &n);
//	while (m != n) //1
//	{
//		while (m > n) m = m - n; //2
//		while (n > m) n = n - m; //3
//	}
//	printf("m=%d\n", m);
//	return 0;
//}
//
//
////3、若运行以下程序时，从键盘输入 ADescriptor<回车> ，则下面程序的运行结果是（ ）
//#include <stdio.h>
//int main()
//{
//	char c;
//	int v0 = 0, v1 = 0, v2 = 0;
//		do
//		{
//			switch (c = getchar())
//			{
//			case'a':case'A':
//			case'e':case'E':
//			case'i':case'I':
//			case'o':case'O':
//			case'u':case'U':v1 += 1;
//			default:v0 += 1; v2 += 1;
//			}
//		} while (c != '\n');
//		printf("v0=%d,v1=%d,v2=%d\n", v0, v1, v2);
//		return 0;
//}
//
//
////4. 如下函数是求两个`int`数字最大公约数的，指出其中存在的问题【多选】（ ）
//int gcd(char x, char y)
//{
//	int min = x < y ? x : y;
//	for (min = 0; min > 0; min--)
//		if (x% min = 0 && y % min = 0)
//			return min;
//}
//
////5. 执行下面的程序段，语句3的执行次数为（ ）
//for (i = 0; i <= n - 1; i++) // (1)
//  for (j = n; j > i; j--) // (2)
//    state; // (3)
//
//
////1、集合 s 包含从 1 到 n 的整数。不幸的是，因为数据错误，导致集合里面某一个数字复制了成了集合里面的另
////外一个数字的值，导致集合 丢失了一个数字 并且 有一个数字重复 。
////给定一个数组 nums 代表了集合 S 发生错误后的结果。
////请你找出重复出现的整数，再找到丢失的整数，将它们以数组的形式返回。
////OJ链接 【 leetcode 题号：645.错误的集合】【难度：简单】
//https://leetcode.cn/problems/set-mismatch/description/
////【答案解析】：
////使用标记的方式就可以找出重复的数字，数组中出现过哪个数字就把对应数字作为下标在对应位置1，表示已经标
////记出现过，如果哪个数据对应位已经置1，则表示就是重复的数字。有了重复的数字，拿[1, n] 的总和减去去掉重复
////数据的数组总和就是丢失的数据。 
////其实使用标记法时出现的数字对应位每次 ++ ，则最后出现0次的就是丢失，出
////现2次的就是重复的，这样的方式也可以，不过需要多次遍历。
//int* findErrorNums(int* nums, int numsSize, int* returnSize) 
//{
//	*returnSize = 2;
//	//遍历nums数组，将其中数据对应的位置1， 哪一位如果已经重置过则意味着数据重复了
//	int* arr = (int*)calloc(numsSize + 1, sizeof(int));//申请numsSize+1个整形空间，并初始化为0
//	int* ret = (int*)calloc(*returnSize, sizeof(int));//申请2个整形空间，并初始化为0
//	int cur_sum = 0, old_sum = 0;
//	for (int i = 0; i < numsSize; i++) 
//	{
//		if (arr[nums[i]] == 1) //这个数字在上边数组的对应位置已经置过1了，则重复
//		{ 
//			ret[0] = nums[i]; //找到重复的数字
//		}
//		arr[nums[i]] = 1; //将标记数组的对应数据位置1
//		old_sum += i + 1; // 1~n的求和
//		cur_sum += nums[i]; //当前数组中的数据求和（多了一个重复的，少了一个丢失的）
//	}
//	ret[1] = old_sum - (cur_sum - ret[0]);//原始总和，减去去掉重复后的当前总和就是丢失的数字
//	free(arr);
//	return ret;
//}


//#include <stdio.h>
//#include <stdlib.h>
//
//int main()
//{
//	int i, n;
//	int* a;
//
//	printf("要输入的元素个数：");
//	scanf("%d", &n);
//
//	a = (int*)calloc(n, sizeof(int));
//	printf("输入 %d 个数字：\n", n);
//	for (i = 0; i < n; i++)
//	{
//		scanf("%d", &a[i]);
//	}
//
//	printf("输入的数字为：");
//	for (i = 0; i < n; i++) 
//	{
//		printf("%d ", a[i]);
//	}
//	printf("\n");
//	free(a);  // 释放内存
//	return(0);
//}


//📌密码检查
//【牛客网链接：OR141 密码检查】
//https://www.nowcoder.com/practice/f2fbd8f61c564ca0b5feaa63ab42dae5?tpId=182&&tqId=34867&rp=1&ru=/ta/exam-all&qru=/ta/exam-all/question-ranking
#include <stdio.h>
#include <string.h>
int main()
{
	int n;
	while (~scanf("%d", &n)) 
	{
		for (int i = 0; i < n; i++) 
		{
			char password[101] = { 0 };
			int upper = 0, lower = 0, digit = 0, other = 0;
			scanf("%s", password);//捕捉输入的密码
			if ( ( strlen(password) < 8 ) || (password[0] >= '0' && password[0] <= '9')) //密码长度小于8 or 密码以数字开头
			{
				printf("NO\n");
				continue; //直接跳出本次循环，执行下一次循环
			}
			char* ptr = password;
			while (*ptr != '\0') //统计各种字符个数
			{ 
				if (*ptr >= 'a' && *ptr <= 'z') lower++; //统计小写字母的个数
				else if (*ptr >= 'A' && *ptr <= 'Z') upper++; //统计大写字母的个数
				else if (*ptr >= '0' && *ptr <= '9') digit++; //统计数字的个数
				else other++; //统计其他字符的个数
				ptr++; 
			}
			if (other > 0) // 有其他字符（注意：密码只能由数字和字母组成）
			{ 
				printf("NO\n");
				continue; //直接跳出本次循环，执行下一次循环
			}
			//大写，小写，数字，必须具有两种以上，而比较运算真则1，假则0
			if ((upper > 0) + (lower > 0) + (digit > 0) < 2) // 密码只有一种字符
			{ 
				printf("NO\n");
				continue; //直接跳出本次循环，执行下一次循环
			}
			printf("YES\n");
		}
	}
	return 0;
}
